using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.IO;


namespace Indie_Game_Contest
{
    //////////////////////////////////////////////////////////////////////////
    // This is the main type for your game
    class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;


        public GraphicsDeviceManager Graphics
        {
            get { return graphics; }
            set { graphics = value; }
        }
        SpriteBatch spriteBatch;

        List<IGameState> states = new List<IGameState>();

        bool exit;
        private static Game1 instance;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

            instance = this;
        }

        //////////////////////////////////////////////////////////////////////////
        // Initialization logic
        protected override void Initialize()
        {
            //////////////////////////////////////////////////////////////////////////
            // TODO: Add your initialization logic here
            AddState(IntroState.Instance);
            WorldData.WindowWidth = Window.ClientBounds.Width;
            WorldData.WindowHeight = Window.ClientBounds.Height;
            Window.Title = "Gossip!: The Musical Beat'em Up Experience";
            base.Initialize();
            WorldData.spriteBatch = spriteBatch;
        }

        //////////////////////////////////////////////////////////////////////////
        // Load sounds,textures,sprite fonts,etc...
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            // TODO: use this.Content to load your game content here
            spriteBatch = new SpriteBatch(GraphicsDevice);

            CleanUp();

            TextureManager tManager = TextureManager.Instance;
            //CTileManager.Instance.NID = tManager.AddTexture(Content.Load<Texture2D>("tileset_32_0"));

            List<string> filepath = new List<string>();

            filepath.Add("block");
            filepath.Add("fence");
            filepath.Add("bush");
            filepath.Add("cloud_1");
            filepath.Add("cloud_2");
            filepath.Add("cloud_3");
            filepath.Add("coin");
            filepath.Add("crate");
            filepath.Add("fence");
            filepath.Add("fence_broken");
            filepath.Add("grass");
            filepath.Add("ground");
            filepath.Add("ground_cave");
            filepath.Add("hill_long");
            filepath.Add("hill_short");
            filepath.Add("shroom");
            filepath.Add("spikes");
            filepath.Add("water");
            filepath.Add("curtains");


            for (int i = 0; i < filepath.Count; ++i)
            {
                Texture2D local = Content.Load<Texture2D>(filepath[i]);
                CTileManager.Instance.TileIDs[filepath[i]] = TextureManager.Instance.AddTexture(local);
            }

            
            int nCurtain = TextureManager.Instance.AddTexture( Content.Load<Texture2D>( "curtains" )  );
            StreamReader read = new StreamReader("highscore.txt");

            string strScore = read.ReadLine();
           int score = int.Parse(strScore);
           read.Dispose();

            HUD.Instance.HighScore = score;

           
            //////////////////////////////////////////////////////////////////////////
            // Load needed assets
            AudioManager AManager = AudioManager.Instance;
            AManager.AddSong("Game Music", Content.Load<Song>(@"Audio\Bob's Adventures - And I must follow if I can"));
            AManager.AddSong("Main Menu", Content.Load<Song>(@"Audio\Bob's Adventures - back34_0"));
            MediaPlayer.IsRepeating = true;



            //  Loading SFX
            OptionsState optionInstance = OptionsState.Instance;
            AudioClip MoveMenu = new AudioClip();
            AudioClip EnterMenu = new AudioClip();
            //SoundEffect menusfx;
            MoveMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\Menu_Move"));
            AManager.AddSFX("Menu_Move", MoveMenu);
            EnterMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\Menu_Enter"));
            AManager.AddSFX("Menu_Enter", EnterMenu);
            EnterMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\Menu_Enter"));

            MoveMenu = new AudioClip();
            MoveMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\punch"));
            AManager.AddSFX("punch", MoveMenu);

            MoveMenu = new AudioClip();
            MoveMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\cheering"));
            AManager.AddSFX("cheer", MoveMenu);

            MoveMenu = new AudioClip();
            MoveMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\meow"));
            AManager.AddSFX("meow", MoveMenu);

            MoveMenu = new AudioClip();
            MoveMenu.LoadContent(1.0f, 0.0f, 0.0f, false, Content.Load<SoundEffect>(@"Audio\applause"));
            AManager.AddSFX("applause", MoveMenu);

            //////////////////////////////////////////////////////////////////////////

            //if (Current_state == IntroState.Instance) // Intro Screen
            {
                SpriteFont font;
                Texture2D  cat,intro_bkgrnd;
               // font2 = Content.Load<SpriteFont>("Gossip");
                //IntroState.Instance.GossipFont1 = TextureManager.Instance.AddSpriteFont(font2);
                intro_bkgrnd = Content.Load < Texture2D>("color_sky_0");
                IntroState.Instance.Intro_background = TextureManager.Instance.AddTexture(intro_bkgrnd);
                font = Content.Load<SpriteFont>("Menufonts");
                IntroState.Instance.IntroFont1 = TextureManager.Instance.AddSpriteFont(font);
                cat = Content.Load<Texture2D>("cat_fighter_sprite2");
                IntroState.Instance.Cats = TextureManager.Instance.AddTexture(cat);
                CatAnimations temp1 = new CatAnimations();
                IntroState.Instance.Cat = temp1;
                IntroState.Instance.Cat.LoadSpiteData(TextureManager.Instance.GetTexture(IntroState.Instance.Cats), 6, 10, 3,50,50);


                font = Content.Load<SpriteFont>("Menufonts");
                int fontID = TextureManager.Instance.AddSpriteFont(font);
                MainMenuSate.Instance.MenuFont1 = fontID;
                OptionsState.Instance.OptionFont = fontID;
                InstructionState.Instance.FontID = fontID;
                GameControlState.Instance.FontID = fontID;

                GameOverState.Instance.FontID = fontID;

                Texture2D left;
                Texture2D right;
                Texture2D jump;

                left = Content.Load<Texture2D>("Left");
                right = Content.Load<Texture2D>("Right");
                jump = Content.Load<Texture2D>("Up");

                GameControlState.Instance.AID = TextureManager.Instance.AddTexture(left);
                GameControlState.Instance.WID = TextureManager.Instance.AddTexture(jump);
                GameControlState.Instance.DID = TextureManager.Instance.AddTexture(right);

                jump = Content.Load<Texture2D>("Empty_Button");
                GameControlState.Instance.SID = TextureManager.Instance.AddTexture(jump);

                jump = Content.Load<Texture2D>("kit_baddie");
                InstructionState.Instance.NKitID = TextureManager.Instance.AddTexture(jump);

                jump = Content.Load<Texture2D>("boxer_baddie");
                InstructionState.Instance.NBoxerID = TextureManager.Instance.AddTexture(jump);

                jump = Content.Load<Texture2D>("cat_pic");
                InstructionState.Instance.NCatID = TextureManager.Instance.AddTexture(jump);

            }
            //else if (Current_state == GameplayState.Instance)
            {
                Texture2D temp;
                temp = Content.Load<Texture2D>("healthbar");
                HUD.Instance.Health= TextureManager.Instance.AddTexture(temp);

                Texture2D rect;
                rect = Content.Load<Texture2D>("cat_fighter_sprite2");

                int id = TextureManager.Instance.AddTexture(rect);
                GameplayState.Instance.PlayerID = id;

                // TEMP
                Texture2D kit;
                kit = Content.Load<Texture2D>("kit");
                GameplayState.Instance.EnemyID = TextureManager.Instance.AddTexture(kit);
                kit = Content.Load<Texture2D>("boxer");
                GameplayState.Instance.BoxerenemyID1 = TextureManager.Instance.AddTexture(kit);
                kit = Content.Load<Texture2D>("fox");
                GameplayState.Instance.FoxenemyID = TextureManager.Instance.AddTexture(kit);

                kit = Content.Load<Texture2D>("pausescreen");
                PauseState.Instance.BgID = TextureManager.Instance.AddTexture(kit);
                Credits.Instance.BgID = PauseState.Instance.BgID;
                GameOverState.Instance.BgID = PauseState.Instance.BgID;
            }
            //else if (Current_state == Credits.Instance)
            {
                SpriteFont font;

                font = Content.Load<SpriteFont>("Menufonts");
                Credits.Instance.CreditFont = TextureManager.Instance.AddSpriteFont(font);
            }

            Texture2D health , life;
            health = Content.Load<Texture2D>("healthbar");
            HUD.Instance.Health = TextureManager.Instance.AddTexture(health);
            life = Content.Load<Texture2D>("music32");
            HUD.Instance.Life_icon = TextureManager.Instance.AddTexture(life);
            SpriteFont HUDfont;
            HUDfont = Content.Load<SpriteFont>("HUDfont");
            HUD.Instance.HudFont = TextureManager.Instance.AddSpriteFont(HUDfont);
           // AManager.PlaySong("Main Menu", true);
        }
        public void AddState(IGameState newState)
        {
            newState.Enter();
            states.Add(newState);
        }
        public void RemoveState()
        {
            Current_state.Exit();
            states.RemoveAt(states.Count-1);

            if (states.Count == 0)
                exit = true;
        }
        public void RemoveState(IGameState state)
        {
            state.Exit();
            states.Remove(state);

            if (states.Count == 0)
                exit = true;
        }
        //////////////////////////////////////////////////////////////////////////
        // Unload sounds,textures,sprite fonts,etc...
        protected override void UnloadContent()
        {
            StreamWriter read = new StreamWriter("highscore.txt");
            read.Write(HUD.Instance.HighScore);

            read.Flush();
            read.Dispose();

            CleanUp();
        }
        void CleanUp()
        {
            TextureManager.Instance.Dispose();
            ObjectManager.Instance.Dispose();
            AudioManager.Instance.UnloadContent();
            CTileManager.Instance.Destrcutor();
        }

        //////////////////////////////////////////////////////////////////////////
        // Main Update
        protected override void Update(GameTime gameTime)
        {
            CInput.Instance.Update();
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || exit )
                this.Exit();


            Current_state.Input();
            Current_state.Update((float)gameTime.ElapsedGameTime.TotalSeconds);


            base.Update(gameTime);
        }

        //////////////////////////////////////////////////////////////////////////
        // Main Render
        protected override void Draw(GameTime gameTime)
        {
            if (Current_state == GameplayState.Instance || Current_state == PauseState.Instance ||
                Current_state == GameOverState.Instance)
                GraphicsDevice.Clear(Color.SkyBlue);
            else
                GraphicsDevice.Clear(Color.IndianRed);

            spriteBatch.Begin();

            foreach(IGameState gs in states)
                gs.Render();


            spriteBatch.End();
            base.Draw(gameTime);
        }

        //////////////////////////////////////////////////////////////////////////
        // Properties
        public static Game1 Instance
        {
            get { return instance; }
        }
        public bool ExitGame
        {
            get { return exit; }
            set { exit = value; }
        }
        public IGameState Current_state
        {
            get { return states[states.Count - 1]; }
        }
    }
}
